from datetime import datetime

import re
import requests
import string
from tqdm import tqdm


# 抖音分享视频链接视频下载
def truncate_before_hash(s):
    index = s.find('#')
    if index != -1:
        return s[:index]
    return s


def remove_illegal_chars(title):
    # 允许的字符包括字母、数字、中文、常见符号
    valid_chars = "-_.() %s%s\u4e00-\u9fff" % (string.ascii_letters, string.digits)
    pattern = re.compile(f'[^{valid_chars}]')
    return pattern.sub('', title)


def download_dy_video(video_url, save_path):
    url_pattern = r'(https?://[^\s]+)'
    match_url = re.search(url_pattern, video_url)
    if match_url is None:
        print("链接解析失败")
        return
    parse_url = match_url.group(1)
    print(f"视频链接：{parse_url}")
    _get_video(parse_url, save_path)


def _get_video(video_url, file_path):
    sess = requests.session()
    headers = {
        'user-agent': 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36',
        'referer': 'https://www.douyin.com/?is_from_mobile_home=1&recommend=1'
    }
    html_text = sess.get(video_url, headers=headers).text
    pattern = r'"play_addr":\{"uri":"([^"]+)"'
    pattern2 = r'"desc":"([^"]+)"'
    match = re.search(pattern, html_text)
    matchtitle = re.search(pattern2, html_text)
    if matchtitle is None:
        print('标题获取失败')
        title = "video_temp_title" + datetime.now().strftime("%Y%m%d")
    else:
        title = truncate_before_hash(matchtitle.group(1))
        title = remove_illegal_chars(title)

    if match:
        print(f"视频标题：{title}")
        uri_value = match.group(1)
        print(f"视频ID：{uri_value}")
        video_url = 'https://www.douyin.com/aweme/v1/play/?video_id=' + uri_value
        print(f"视频播放地址：{video_url}")
        resp3 = sess.get(video_url, headers=headers, stream=True)
        if resp3.status_code == 200:
            total_size = int(resp3.headers.get('content-length', 0))
            with open(file_path + '/' + title + '.mp4', 'wb') as f:
                with tqdm(total=total_size, unit='B', unit_scale=True, desc=title) as pbar:
                    for chunk in resp3.iter_content(chunk_size=1024):
                        if chunk:
                            f.write(chunk)
                            pbar.update(len(chunk))
            print("视频保存成功！")
        else:
            print(f"请求视频失败，状态码: {resp3.status_code}")
    else:
        print("未找到匹配的uri值")


if __name__ == "__main__":
    url = "8.25 s@E.hB yGI:/ 06/05 复制打开抖音，看看【发哥交易哲学的作品】题材明显高低切换，究竟要如何选择，AI or 新能... https://v.douyin.com/OO_BamIfKE4/ "
    save_path = "/Users/decheng/Downloads/dy_download"
    download_dy_video(url, save_path)
